package com.sdnu.iosclub.qvs.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sdnu.iosclub.qvs.entity.QvsOption;
import com.sdnu.iosclub.qvs.entity.QvsQuestion;
import com.sdnu.iosclub.qvs.entity.vo.QvsVoterVo;
import com.sdnu.iosclub.qvs.mapper.QvsOptionMapper;
import com.sdnu.iosclub.qvs.mapper.QvsQuestionMapper;
import com.sdnu.iosclub.qvs.service.QvsOptionService;
import com.sdnu.iosclub.qvs.service.QvsQuestionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wcr
 * @since 2022-09-05
 */
@Service
@CacheConfig(cacheNames = "question")
public class QvsQuestionServiceImpl extends ServiceImpl<QvsQuestionMapper, QvsQuestion> implements QvsQuestionService {

    @Autowired
    QvsOptionService qvsOptionService;

    @Autowired
    private QvsOptionMapper qvsOptionMapper;

    @Override
    public List<QvsQuestion> getAllQuestion() {
        QueryWrapper<QvsQuestion> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("update_time");
        return this.list(wrapper);
    }

    @Override
    public Page<QvsQuestion> pageGetQuestion(long current, long size) {
        Page<QvsQuestion> page = new Page<>(current,size);
        QueryWrapper<QvsQuestion> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("update_time");
        this.page(page,wrapper);
        return page;
    }

    @Override
    public boolean addQuestion(QvsQuestion qvsQuestion) {
        return this.save(qvsQuestion);
    }

    @Override
    public boolean updateQuestion(QvsQuestion qvsQuestion) {
        return this.updateById(qvsQuestion);
    }

    @Override
    public boolean deleteQuestion(String id) {
        QueryWrapper<QvsQuestion> wrapper = new QueryWrapper<>();
        wrapper.eq("id",id);
        return this.remove(wrapper);
    }

    @Override
    public boolean addQuestionInfo(QvsQuestion qvsQuestion) {
        boolean questionDone = this.save(qvsQuestion);
        boolean optionDone = true;
        for(QvsOption qvsOption : qvsQuestion.getOptions()){
            qvsOption.setQuestionId(qvsQuestion.getId());
            qvsOption.setSurveyId(qvsQuestion.getSurveyId());
            if(!qvsOptionService.addOption(qvsOption)){
                optionDone = false;
                break;
            }
        }
        return questionDone && optionDone;
    }

    @Override
    public List<QvsVoterVo> getVotersByIdSet(Set<String> set,QvsVoterVo qvsVoterVo) {
        return baseMapper.getVotersByIdSet(set,qvsVoterVo);
    }

    /**
     * 添加或修改一个问卷的所有问题，即添加完问卷本身的信息之后，再添加或修改问卷的所有问题
     * @param qvsQuestionList 问题的列表
     * @return 添加或修改是否成功
     */
    @Override
    //因为在配置文件中配置了，所以默认会使用数据源的事务管理器
    @Transactional
    public boolean addSurveyQuestionList(List<QvsQuestion> qvsQuestionList) {

        //首先将所有题目都插入到数据库，对于选择题，还需要根据其插入后的主键插入选项
        //使用插入或者更新，因为中间有可能更新的
        boolean qvFlag = this.saveOrUpdateBatch(qvsQuestionList);
        //获取选择题类型的题目，如果其选项是新加的，就给他设置上问题的id
        List<QvsQuestion> qvsOptionQuestions = qvsQuestionList.stream()
                .filter(qvsQuestion -> qvsQuestion.getOptions() != null && qvsQuestion.getOptions().size()>0)
                .peek(qvsQuestion -> {
                    qvsQuestion.setOptions(
                            qvsQuestion.getOptions().stream()
                            .peek(qvsOption ->{
                                if(StringUtils.isEmpty(qvsOption.getQuestionId())){
                                    qvsOption.setQuestionId(qvsQuestion.getId());
                                }
                            })
                            .collect(Collectors.toList())
                    );
                })
                .collect(Collectors.toList());

        //获取所有的选项
        List<QvsOption> qvsOptionList = new ArrayList<>(qvsOptionQuestions.size()*2);
        qvsOptionQuestions.forEach(qvsQuestion -> {
            qvsOptionList.addAll(qvsQuestion.getOptions());
        });
        //批量插入所有选项
        boolean opFlag = true;
        if(qvsOptionList.size()>0){
            opFlag = qvsOptionService.saveOrUpdateBatch(qvsOptionList);
        }
        return qvFlag && opFlag;
    }

    /**
     * 删除问题及其选项，直接删除（非逻辑删除）
     *
     * @param qvsQuestion 问题
     * @return 是否删除成功
     */
    @Override
    @Transactional
    public boolean deleteQuestionInfo(QvsQuestion qvsQuestion) {
        //先删除问题
        boolean flag = baseMapper.deleteQuestionById(qvsQuestion.getId()) >0;
        //再判断问题是否有选项，若有就删除。传过来的问题如果有选项前端让他会带着选项传递过来
        if(qvsQuestion.getOptions() != null && qvsQuestion.getOptions().size()>0){
            //根据问题id批量删除选项
            qvsOptionMapper.deleteBatchByQuestionId(qvsQuestion.getId());
        }
        return flag;
    }
}
